package util;

import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.message.MessageFactory2;
import org.apache.logging.log4j.message.ParameterizedMessageFactory;
import org.apache.logging.log4j.message.ReusableMessageFactory;
import org.apache.logging.log4j.spi.MessageFactory2Adapter;
import org.apache.logging.log4j.util.Constants;
import org.apache.logging.log4j.util.LoaderUtil;
import org.apache.logging.log4j.util.PropertiesUtil;
import org.slf4j.Logger;

/**
 *  
 * @author zhangweilin
 * @date 2023/3/2 10:41
 * @Description:
 */
@LocationIdExclude
public class LogUtil {

	private static final MessageFactory2 messageFactory = createDefaultMessageFactory();

	/**
	 * error日志
	 * @author zhangweilin
	 * @date 2023/3/2 10:41
	 * @Description:
	 */
	public static void error(Logger log, String message) {
		try {
			throw new zwlBaseException(message);
		} catch (Throwable e) {
			log.error(SceneUtil.buildErrorMsg(message, e),e);
		}
	}

	/**
	 * error日志
	 * @author zhangweilin
	 * @date 2023/3/2 10:41
	 * @Description:
	 */
	public static void error(Logger log, String message, Object... arguments) {
		try {
			Message message1 = messageFactory.newMessage(message, arguments);
			throw new zwlBaseException(message1.getFormattedMessage());
		} catch (Throwable e) {
			String msg = SceneUtil.buildErrorMsg(e.getMessage(), e);
			log.error(msg,e);
		}
	}

	/**
	 * error日志
	 * @author zhangweilin
	 * @date 2023/3/2 10:41
	 * @Description:
	 */
	public static void error(Logger log, String message, Throwable t) {
		String msg = SceneUtil.buildErrorMsg(message, t);
		log.error(msg,t);
	}

	/**
	 * error日志
	 * @author zhangweilin
	 * @date 2023/3/2 10:41
	 * @Description:
	 */
	public static void error(Logger log, Throwable t, String message, Object... arguments) {
		Message message1 = messageFactory.newMessage(message, arguments);
		String msg = SceneUtil.buildErrorMsg(message1.getFormattedMessage(), t);
		log.error(msg,t);
	}

	private static Class<? extends MessageFactory> createClassForProperty(final String property,
			final Class<ReusableMessageFactory> reusableParameterizedMessageFactoryClass,
			final Class<ParameterizedMessageFactory> parameterizedMessageFactoryClass) {
		try {
			final String fallback = Constants.ENABLE_THREADLOCALS ?
					reusableParameterizedMessageFactoryClass.getName() :
					parameterizedMessageFactoryClass.getName();
			final String clsName = PropertiesUtil.getProperties().getStringProperty(property, fallback);
			return LoaderUtil.loadClass(clsName).asSubclass(MessageFactory.class);
		} catch (final Throwable throwable) {
			return parameterizedMessageFactoryClass;
		}
	}

	private static MessageFactory2 createDefaultMessageFactory() {
		try {
			Class<? extends MessageFactory> classForProperty = createClassForProperty("log4j2.messageFactory", ReusableMessageFactory.class,
					ParameterizedMessageFactory.class);

			final MessageFactory result = classForProperty.newInstance();
			return narrow(result);
		} catch (final InstantiationException | IllegalAccessException e) {
			throw new IllegalStateException(e);
		}
	}

	private static MessageFactory2 narrow(final MessageFactory result) {
		if (result instanceof MessageFactory2) {
			return (MessageFactory2) result;
		}
		return new MessageFactory2Adapter(result);
	}
}
